interface Executor {
    (fn: (message: string) => void) : void
}

class Cancel {
    message: string
    __CANCEL__: boolean = true
    constructor(message: string) {
        this.message = message
    }
    toString(): string {
        return 'Cancel' + (this.message ? ': ' + this.message : '');
    }
}
/**
 * 取消请求，在发请求前设置promise的resolve回调，然后通过 cancel 去触发 promise 从而执行之前设置
 * 的回调，调用 request.abort() 取消请求
 */
export default class CancelToken {
    reason: Cancel
    promise: Promise<Cancel>
    static source() {
        let cancel: (message: string) => void;
        let token = new CancelToken(function executor(c) {
            cancel = c;
        });
        return {
            token: token,
            cancel: cancel
        };
    }
    constructor(executor: Executor) {
        if (typeof executor !== 'function') {
            throw new TypeError('executor must be a function.');
        }
        let token = this;
        let resolvePromise: (value?: Cancel | PromiseLike<Cancel>) => void
        this.promise = new Promise(function promiseExecutor(resolve) {
            resolvePromise = resolve;
        });
        executor(function cancel(message: string) {
            if (token.reason) return;
            token.reason = new Cancel(message);
            resolvePromise(token.reason);
        });
    }
    // 请求成功的时候取消请求则抛出错误
    throwIfRequested() {
        if (this.reason) {
            throw this.reason;
        }   
    }
}